﻿using System;
using sorTV.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Globalization;
using System.Xml.XPath;
using System.IO;
using sorTV.Interface;


namespace sorTV.Controller
{
    /// <summary>
    /// Lavet af Rasmus, Ole og Søren.
    /// </summary>
    public static class XMLParser
    {
        /// <summary>
        /// Lavet af Rasmus - Bruges til at 0-køre databasen
        /// </summary>
        public static void NulKørsel(string xmlSti)
        {

            DBController dbCon = new DBController();

            List<GeoKommune> kommuneCheckListe = new List<GeoKommune>();
            List<Liste> listeCheckListe = new List<Liste>();
            List<Kandidat> kandidatCheckListe = new List<Kandidat>();
         
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlSti);

            #region VALGGEOGRAFI
            foreach (XmlNode valgGeografiNode in doc.GetElementsByTagName("VALGGEOGRAFI"))
            {
                foreach (XmlNode valgGeografiNodeChildNodes in valgGeografiNode.ChildNodes)
                {
                    GeoAmtstorkreds amtstorkreds = new GeoAmtstorkreds(int.Parse(valgGeografiNodeChildNodes.Attributes["id"].Value), valgGeografiNodeChildNodes.Attributes["navn"].Value);
                    dbCon.SPF1_0Kørsel_GeoAmtstorkreds(amtstorkreds,dbCon.OpenConnection(1));
                    dbCon.CloseConnection(1);

                    foreach (XmlNode valgGeografiNodeChildNodeChildNodes in valgGeografiNodeChildNodes.ChildNodes)
                    {
                        GeoValgKreds valgkreds = new GeoValgKreds(int.Parse(valgGeografiNodeChildNodeChildNodes.Attributes["id"].Value), valgGeografiNodeChildNodeChildNodes.Attributes["navn"].Value);
                        dbCon.SPF1_0Kørsel_GeoValgkreds(valgkreds, dbCon.OpenConnection(1));
                        dbCon.CloseConnection(1);

                        foreach (XmlNode valgGeografiNodeChildNodeChildNodeChildNodes in valgGeografiNodeChildNodeChildNodes.ChildNodes)
                        {
                            GeoKommune kommune = new GeoKommune(int.Parse(valgGeografiNodeChildNodeChildNodeChildNodes.Attributes["id"].Value), valgGeografiNodeChildNodeChildNodeChildNodes.Attributes["navn"].Value);

                            if (!kommuneCheckListe.Exists(x => x.KommuneID == kommune.KommuneID))
                            {
                                dbCon.SPF1_0Kørsel_GeoKommune(kommune, dbCon.OpenConnection(1));
                                kommuneCheckListe.Add(kommune);
                                dbCon.CloseConnection(1);
                            }

                            foreach (XmlNode valgGeografiNodeChildNodeChildNodeChildNodeChildNodes in valgGeografiNodeChildNodeChildNodeChildNodes.ChildNodes)
                            {
                                GeoDistrikt distrikt = new GeoDistrikt(int.Parse(valgGeografiNodeChildNodeChildNodeChildNodeChildNodes.Attributes["id"].Value), valgGeografiNodeChildNodeChildNodeChildNodeChildNodes.Attributes["navn"].Value, valgGeografiNodeChildNodeChildNodeChildNodeChildNodes.Attributes["sted1"].Value, valgGeografiNodeChildNodeChildNodeChildNodeChildNodes.Attributes["sted2"].Value, valgGeografiNodeChildNodeChildNodeChildNodeChildNodes.Attributes["sted3"].Value, int.Parse(valgGeografiNodeChildNodeChildNodeChildNodes.Attributes["id"].Value));
                                dbCon.SPF1_0Kørsel_GeoDistrikt(distrikt, dbCon.OpenConnection(1));
                                dbCon.CloseConnection(1);
                            }
                        }
                    }
                }
            } 
            #endregion
 
            #region Kandidater og Liste

            /*foreach (XmlNode MainNode in doc.GetElementsByTagName("LISTE"))
            {
                Liste liste = new Liste(MainNode.Attributes["bogstav"].Value, MainNode.Attributes["navn"].Value, int.Parse(MainNode.Attributes["stemmetal"].Value), decimal.Parse(MainNode.Attributes["pct"].Value), int.Parse(MainNode.Attributes["forrige_stemmetal"].Value), decimal.Parse(MainNode.Attributes["forrige_pct"].Value));
                        if (!listeCheckListe.Exists(x=> x.Bogstav == liste.Bogstav))
                        {
                            dbCon.SPF1_0Kørsel_Liste(liste);
                            listeCheckListe.Add(liste);
                        }
                        /*foreach (XmlNode MainNodeChildNodes in MainNode.ChildNodes)
                        {
                            Kandidat kandidat = new Kandidat(liste.Bogstav, int.Parse(MainNodeChildNodes.Attributes["stemmetal"].Value), MainNodeChildNodes.Attributes["navn"].Value);

                            if (!kandidatCheckListe.Exists(x=> x.Navn == kandidat.Navn))
                            {
                                dbCon.SPF1_0Kørsel_Kandidat(kandidat);
                                kandidatCheckListe.Add(kandidat);
                            }
                            
                        }
            }*/

            #endregion
          
        }

        /// <summary>
        /// Lavet af Søren og Ole - Bruges til at parse XML-filer, 
        /// som kommer ind fra feedet og lægges derefter ind i et transport-objekt.
        /// </summary>
        /// <param name="xmlFil"></param>
        /// <returns></returns>
        public static List<IValgData> ParseXML(XmlDocument xmlFil)
        {

            List<IValgData> tempListe = new List<IValgData>();
            using (XmlReader reader = new XmlNodeReader(xmlFil))
            {
                reader.MoveToContent();
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element && reader.Name == "VALGDATA")
                    {
                        int valgfase = int.Parse(reader.GetAttribute("valgfase"));
                        string valgtype = reader.GetAttribute("type");

                        switch (valgtype)
                        {
                            #region CASE Kommune
                            case "kommune":
                                Kommune kom = new Kommune(valgtype,valgfase,DateTime.Parse(reader.GetAttribute("timestamp")), int.Parse(reader.GetAttribute("amt_stor_kreds")),
                                                          reader.GetAttribute("valgart"), int.Parse(reader.GetAttribute("kommune")));

                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    kom.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            kom.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(kom);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                                                                              decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            kom.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(kom);
                                    }
                                }

                                break;
                            #endregion

                            #region CASE Afstemningsområde
                            case "afstemningsområde":
                                Afstemningsområde ao = new Afstemningsområde(valgtype, valgfase,DateTime.Parse(reader.GetAttribute("timestamp")),
                                                                            int.Parse(reader.GetAttribute("amt_stor_kreds")), reader.GetAttribute("valgart"),
                                                                            int.Parse(reader.GetAttribute("kreds")),int.Parse(reader.GetAttribute("kommune")), int.Parse(reader.GetAttribute("sted")));
                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    ao.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            ao.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(ao);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            ao.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(ao);
                                    }
                                }

                                break;
                            #endregion

                            #region CASE Kreds
                            case "kreds":           
                                Kreds kreds = new Kreds(valgtype, valgfase,DateTime.Parse(reader.GetAttribute("timestamp")), int.Parse(reader.GetAttribute("amt_stor_kreds")), 
                                                        reader.GetAttribute("valgart"), int.Parse(reader.GetAttribute("kreds")));

                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    kreds.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            kreds.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(kreds);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            kreds.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        tempListe.Add(kreds);
                                    }
                                }

                                break;
                            #endregion
                        }
                    }
                }
            }
            return tempListe;
        }

        public static Valgdata ParseXMLTest(string xmlFil)
        {
            Valgdata valg = null;
            using (XmlReader reader = XmlReader.Create(xmlFil))
            {
                reader.MoveToContent();
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element && reader.Name == "VALGDATA")
                    {
                        int valgfase = int.Parse(reader.GetAttribute("valgfase"));
                        string valgtype = reader.GetAttribute("type");

                        switch (valgtype)
                        {
                            #region CASE Kommune
                            case "kommune":
                                Kommune kom = new Kommune(valgtype, valgfase, DateTime.Parse(reader.GetAttribute("timestamp")), int.Parse(reader.GetAttribute("amt_stor_kreds")),
                                                          reader.GetAttribute("valgart"), int.Parse(reader.GetAttribute("kommune")));

                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    kom.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            kom.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (kom);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                                                                              decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            kom.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (kom);
                                    }
                                }

                                break;
                            #endregion

                            #region CASE Afstemningsområde
                            case "afstemningsområde":
                                Afstemningsområde ao = new Afstemningsområde(valgtype, valgfase, DateTime.Parse(reader.GetAttribute("timestamp")),
                                                                            int.Parse(reader.GetAttribute("amt_stor_kreds")), reader.GetAttribute("valgart"),
                                                                            int.Parse(reader.GetAttribute("kreds")), int.Parse(reader.GetAttribute("kommune")), int.Parse(reader.GetAttribute("sted")));
                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    ao.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            ao.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (ao);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            ao.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (ao);
                                    }
                                }

                                break;
                            #endregion

                            #region CASE Kreds
                            case "kreds":
                                Kreds kreds = new Kreds(valgtype, valgfase, DateTime.Parse(reader.GetAttribute("timestamp")), int.Parse(reader.GetAttribute("amt_stor_kreds")),
                                                        reader.GetAttribute("valgart"), int.Parse(reader.GetAttribute("kreds")));

                                reader.ReadToDescendant("STEMMER");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "STEMMER")
                                {
                                    kreds.Stemme = new Stemme(decimal.Parse(reader.GetAttribute("stemme_pct"), new CultureInfo("en-US")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("stemmeberettigede")),
                                                            int.Parse(reader.GetAttribute("ugyldige")), int.Parse(reader.GetAttribute("forrige_ugyldige")), int.Parse(reader.GetAttribute("blanke")),
                                                            int.Parse(reader.GetAttribute("forrige_blanke")), int.Parse(reader.GetAttribute("forrige_rest")), int.Parse(reader.GetAttribute("ialt_afgiv")));
                                }

                                reader.ReadToDescendant("LISTE");
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LISTE")
                                {
                                    if (valgfase == 2)
                                    {
                                        do
                                        {
                                            kreds.Stemme.Lister.Add(new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                                  decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")), decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US"))));
                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (kreds);
                                    }

                                    else if (valgfase == 4)
                                    {
                                        Liste temp;

                                        do
                                        {
                                            temp = new Liste(reader.GetAttribute("bogstav"), reader.GetAttribute("navn"), int.Parse(reader.GetAttribute("stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("pct"), new CultureInfo("en-US")), int.Parse(reader.GetAttribute("forrige_stemmetal")),
                                                             decimal.Parse(reader.GetAttribute("forrige_pct"), new CultureInfo("en-US")));
                                            reader.ReadToDescendant("KANDIDAT");
                                            do
                                            {
                                                temp.Kandidater.Add(new Kandidat(int.Parse(reader.GetAttribute("stemmetal")), reader.GetAttribute("navn")));
                                            } while (reader.ReadToNextSibling("KANDIDAT"));

                                            kreds.Stemme.Lister.Add(temp);

                                        } while (reader.ReadToNextSibling("LISTE"));
                                        valg = (kreds);
                                    }
                                }

                                break;
                            #endregion
                        }
                    }
                }
            }
            return valg;
        }

    }
}
